﻿/**
 * Safe Pad, a double encrypted note pad that uses 2 passwords to protect your documents and help you keep your privacy.
 * 
 * Copyright (C) 2014 Stephen Haunts
 * http://www.stephenhaunts.com
 * 
 * This file is part of Safe Pad.
 * 
 * Safe Pad is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 2 of the
 * License, or (at your option) any later version.
 * 
 * Safe Pad is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * 
 * See the GNU General Public License for more details <http://www.gnu.org/licenses/>.
 * 
 * Authors: Stephen Haunts
 */
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using HauntedHouseSoftware.SecureNotePad.DomainObjects;
using System.Collections;

namespace HauntedHouseSoftware.SecureNotePad.Tests.Unit.DomainObjects
{
    [TestClass]
    public class GZipCompressionTests
    {
        readonly byte[] _inputData = {0x01,0xE5,0x92,0xBC,0xE6,0xA4,0xBE,0xE6,0xA3,0x8D,0xE7,0x9B,0x90,0xED,0xBF,0xB1,
                                      0xED,0x84,0x82,0xEA,0xBD,0x8C,0xEC,0xAA,0xA9,0xE5,0xB7,0x9B,0xE9,0x92,0x9A,0xE8,
                                      0x81,0x83,0xE0,0xAE,0xAC,0xE4,0xAF,0x9C,0xE9,0xB2,0x95,0xE7,0x86,0x99,0xE2,0x9D,
                                      0x82,0xE7,0x83,0x83,0xEE,0x99,0x9F,0xE1,0x8C,0xA5,0xEF,0x92,0x9D,0xE5,0xB5,0xAA,
                                      0xEE,0xB0,0x93,0xE4,0xA0,0x89,0xEC,0x98,0x93,0xEA,0xB1,0x8B,0xE1,0xA5,0x90,0xE9,
                                      0xBB,0x8A,0xE1,0xB8,0xA1,0xED,0xA9,0xA4,0xE5,0xB0,0x9C,0xEF,0x89,0xBA,0xEC,0x8F,
                                      0xB0,0xEF,0x9E,0xAB,0xE7,0x8C,0x93,0xE8,0xAD,0x80,0xE7,0xAE,0xAF,0xEE,0xAB,0xB0,
                                      0xE8,0x87,0x81,0xED,0x9C,0x9E,0xE0,0xB3,0x8B,0xED,0xAB,0xA7,0xED,0x8F,0xBF,0xEF,
                                      0xBA,0x95,0xEA,0xB2,0xA6,0xEB,0x86,0x96,0xE0,0xBA,0xA5,0xEB,0xBA,0xA0,0xE4,0xBD,
                                      0xB0,0xEA,0x81,0x82,0xEA,0x97,0xA8,0xE1,0x9A,0xAB,0xEE,0x93,0x91,0xEF,0x8C,0x9B,
                                      0xEC,0x90,0xA3,0xE6,0xA6,0xB4,0xE2,0xAC,0xA6,0xED,0x85,0xB0,0xED,0xAA,0xAC,0xEE,
                                      0x9D,0x9B,0xEB,0x8F,0x84,0xE6,0x9F,0x8E,0xEC,0xA2,0xB5,0xCA,0xA1,0xE5,0xA3,0xAD,
                                      0xE5,0xB8,0x9D,0xEA,0xAC,0x92,0xE4,0x93,0xAD,0xE3,0xAA,0x8A,0xED,0x97,0xAB,0xE1,
                                      0xBA,0x94,0xE1,0x81,0x81,0xE6,0x92,0xA3,0xEB,0x84,0xA9,0xE9,0x91,0x9F,0xEC,0x91,
                                      0xB9,0xE6,0x99,0x96,0xE7,0x98,0xBE,0xE8,0x8E,0x92,0xD2,0xB4,0xE1,0x9A,0xBC,0xED,
                                      0x8F,0x93,0xEE,0x81,0xB3,0xE8,0x99,0xBB,0xE7,0xAD,0x9C,0xEB,0x92,0x84,0xE2,0xA4,
                                      0x9E,0xE6,0xBF,0x99,0xE2,0xA7,0x94,0xE3,0xAD,0x82,0xEC,0x89,0x9E,0xEF,0xBE,0xB3,
                                      0xE6,0xBB,0x8B,0xE5,0xA7,0xAB,0xE0,0xB5,0x96,0xE8,0xBA,0xB6,0xE6,0x8D,0x81,0xEF,
                                      0xA9,0x9F,0xE5,0xA3,0x90,0xE5,0xAC,0x99,0xE3,0xA0,0x9D,0xEE,0x8B,0x8C,0xE8,0xA5,
                                      0xAE,0xE5,0xB6,0x9B,0xE8,0x88,0xA2};

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException), "input")]
        public void CompressThrowsArgumentNullExceptionIfInputDataIsNull()
        {
            new GZipCompression().Compress(null);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException), "input")]
        public void DecompressThrowsArgumentNullExceptionIfInputDataIsNull()
        {
            new GZipCompression().Decompress(null);
        }

        [TestMethod]        
        public void CompressReturnsByteArray()
        {
            ICompression compression = new GZipCompression();
            byte[] compressed = compression.Compress(_inputData);
            Assert.IsNotNull(compressed);
        }

        [TestMethod]
        public void CompressReducesSizeOfByteArray()
        {
            ICompression compression = new GZipCompression();
            byte[] compressed = compression.Compress(_inputData);
            Assert.IsTrue(compressed.Length < _inputData.Length);
        }


        [TestMethod]
        public void DecompressReturnsByteArray()
        {
            ICompression compression = new GZipCompression();
            byte[] compressed = compression.Compress(_inputData);
            byte[] decompressed = compression.Decompress(compressed);

            Assert.IsNotNull(decompressed);
        }

        [TestMethod]
        public void DecompressReturnsByteArrayThatIsTheSameSizeAsTheOriginal()
        {
            ICompression compression = new GZipCompression();
            byte[] compressed = compression.Compress(_inputData);
            byte[] decompressed = compression.Decompress(compressed);

            Assert.IsTrue(decompressed.Length == _inputData.Length);
        }

        [TestMethod]
        public void DecompressReturnsByteArrayThatIsTheSameAsTheOriginal()
        {
            ICompression compression = new GZipCompression();
            byte[] compressed = compression.Compress(_inputData);
            byte[] decompressed = compression.Decompress(compressed);

            Assert.IsFalse(ByteArrayCompare(decompressed, _inputData));
        }

        private static bool ByteArrayCompare(byte[] a1, byte[] a2)
        {
            IStructuralEquatable eqa1 = a1;
            return !eqa1.Equals(a2, StructuralComparisons.StructuralEqualityComparer);
        }
    }
}
